package cn.le.studyEnum;

import java.util.EnumSet;

/**
 * EnumSet是为了通过enum创建一种替代品，以替代传统的基于int的“位标志”。这种标志可以用来表示某种
 * “开/关”信息，不过，使用这种标志，我们最终操作的只是一些bit，而不是这些bit想要表达的概念，因此很容易写出
 * 令人难以理解的代码。
 * 一个long值有64位，而一个enum实例只需要一位bit表示其是否存在，一般情况enumset可以应用与最多不超过64个元素的enum，
 * 但实际情况enumset可以超过64位，Enum会在必要的时候增加一个long
 *
 * EnumSet非常的快速高效，因为它必须与非常高效的bit标志相竟争，它内部可能是将一个long直作为
 * 比特向量。
 *
 * EnumSet的顺序取决于enum实例定义的次序
 *
 * 优点：它在说明一个二进制位是否存在时，具有更好的表达能力，并且无需担心性能
 *
 */
public class EnumSets {

    public static void main(String[] args) {
        //创建一个具有指定元素类型的空枚举 set
        EnumSet<AlarmPoints> points = EnumSet.noneOf(AlarmPoints.class);
        points.add(AlarmPoints.BATHROOM);
        System.out.println("add:"+points);
        //of(): 创建一个最初包含指定元素的枚举 set
        points.addAll(EnumSet.of(AlarmPoints.STAIR1,AlarmPoints.STAIR2,AlarmPoints.KITCHEN));
        System.out.println("of:"+EnumSet.of(AlarmPoints.STAIR1,AlarmPoints.STAIR2,AlarmPoints.KITCHEN));
        System.out.println("addAll of:"+points);
        //allOf():创建一个包含指定元素类型的所有元素的枚举 set。
        points = EnumSet.allOf(AlarmPoints.class);
        System.out.println("allof:"+EnumSet.allOf(AlarmPoints.class));
        points.removeAll(EnumSet.of(AlarmPoints.STAIR1,AlarmPoints.STAIR2,AlarmPoints.KITCHEN));
        System.out.println("removeAll:"+points);
        //range():创建一个最初包含由两个指定端点所定义范围内的所有元素的枚举 set。
        // 返回的 set 将包含端点本身，这两个端点可能相同，但顺序不能颠倒
        points.removeAll(EnumSet.range(AlarmPoints.OFFICE1,AlarmPoints.OFFICE4));
        System.out.println("range:"+EnumSet.range(AlarmPoints.OFFICE1,AlarmPoints.OFFICE4));
        System.out.println("removeAll:"+points);
        //创建一个其元素类型与指定枚举 set 相同的枚举 set，最初包含指定 set 中所不包含的此类型的所有元素。
        points = EnumSet.complementOf(points);
        System.out.println("complementOf:"+EnumSet.complementOf(points));
        System.out.println(points);
    }

}

enum AlarmPoints  {
    STAIR1,STAIR2,LOBBY,OFFICE1,OFFICE2,OFFICE3,OFFICE4,
    BATHROOM,UTILITY,KITCHEN;
}